package gates;

/**
 *
 * A representation of a toffoli gate made out of several other gates, the Hadamard, T, TDagger, S and CNot
 * This representation can be found in <a href="http://arxiv.org/abs/quant-ph/0301079">Grover's Algorithm: Quantum Database Search</a> page 26
 * @author Alex Bush
 *
 */
public class ToffoliComposite extends CompositeGate {

	/**
	 * Protected constructor to create an instance of this object
	 * 
	 * @param control1 First control bit
	 * @param control2 Second control bit
	 * @param target Target bit
	 */
	protected ToffoliComposite(int control1, int control2, int target) {
		super(createGates(control1,control2,target));
	}
	
	/** Private method to create an array of gates needed to create a composition to send to superclass */
	private static Gate[] createGates(int control1, int control2, int target){
		// Test arguments and throw appropriate exception
		if (control1 == control2 || control1 == target || control2 == target){
			throw new IllegalArgumentException("Control1, control2 and target must be unique");
		}
		Gate[] tg = new Gate[16];
		tg[0] = Factory.createHadamard(target);
		tg[1] = Factory.createCNot(control2, target);
		tg[2] = Factory.createTDagger(target);
		tg[3] = Factory.createCNot(control1, target);
		tg[4] = Factory.createT(target);
		tg[5] = Factory.createCNot(control2, target);
		tg[6] = Factory.createTDagger(target);
		tg[7] = Factory.createCNot(control1, target);
		tg[8] = Factory.createTDagger(control2);
		tg[9] = Factory.createT(target);
		tg[10] = Factory.createCNot(control1, control2);
		tg[11] = Factory.createHadamard(target);
		tg[12] = Factory.createTDagger(control2);
		tg[13] = Factory.createCNot(control1, control2);
		tg[14] = Factory.createT(control1);
		tg[15] = Factory.createS(control2);
		return tg;

	}

}
